import { createLogger, transports, format } from "winston";
import { format as formatDate } from "ph-utils/date";
import { isBlank } from "ph-utils";
const { combine, timestamp, printf } = format;

let defaultLabel = "LOGGER";

const OutputFormat = printf(({ level, message, label, timestamp }) => {
  return `${timestamp} ${
    label ? label : defaultLabel
  } [${level.toUpperCase()}]: ${message}`;
});

export let logger;

/**
 * 初始化日志
 *
 * @param level 日志级别
 * @param {string|null} label 日志标签
 */
export function initLogger(level = "info", label = null) {
  if (!isBlank(label)) {
    defaultLabel = label;
  }
  logger = createLogger({
    format: combine(
      timestamp({
        format() {
          return formatDate(undefined, "yyyy-mm-dd HH:MM:ss.S");
        },
      }),
      OutputFormat
    ),
    level: level,
    transports: [new transports.Console()],
    rejectionHandlers: [new transports.Console()],
  });
}

/**
 * @typedef LogOption
 * @property {string} [level] - 日志级别
 * @property {string | Error} message - 日志信息
 * @property {string} [prefix] - 日志前缀
 */

/**
 * 写日志
 *
 * @param {string | LogOption} msg - 日志信息或者日志选项
 */
export const log = function (msg) {
  if (logger == null) return;
  if (msg instanceof Error) {
    logger.error(msg.stack);
  } else if (typeof msg === "string") {
    logger.info(msg);
  } else {
    if (msg.message == null) {
      logger.info(JSON.stringify(msg));
    } else {
      let level = msg.level || "info";
      let message = msg.message;
      if (msg.message instanceof Error) {
        level = "error";
        message = msg.message.stack;
      }
      if (typeof message === "object") {
        message = JSON.stringify(message);
      }
      if (msg.prefix) {
        message = `${msg.prefix}: ${message}`;
      }
      const logMsg = {
        level: level,
        message,
        label: msg.label,
      };
      logger.log(logMsg);
    }
  }
};
